﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.Win32;
using System.Text.RegularExpressions;

namespace MyPublisher.Framework
{
    public class LocalTypesFactory : TypesFactory
    {
        static string[] filters = new string[]
                                    {
                                        ".doc",
                                        ".docx",
                                        ".pptx",
                                        ".ppt",
                                        ".pdf",
                                        ".zip",
                                        ".rar",
                                    };
        private List<ApplicationType> appliationTypes;
        private List<ProcessType> processTypes;
        private List<LocationType> locationTypes;
        private List<ConnectorType> connectorTypes;
        private Thread thread;

        public LocalTypesFactory()
        {
            this.appliationTypes = new List<ApplicationType>();
            this.processTypes = new List<ProcessType>();
            this.locationTypes = new List<LocationType>();
            this.connectorTypes = new List<ConnectorType>();
            this.thread = new Thread(SearchTypes);
            this.thread.Start();

            SearchLocationTypes();
        }

        public override IList<ApplicationType> ApplicationTypes { get { return appliationTypes; } }
        public override IList<ProcessType> ProcessTypes { get { return processTypes; } }
        public override IList<LocationType> LocationTypes { get { return locationTypes; } }
        public override IList<ConnectorType> ConnectorTypes { get { return connectorTypes; } }

        private void SearchTypes()
        {
            SearchApplicationTypes();
            SearchProcessTypes();
            //SearchLocationTypes();
            SearchConnectorTypes();
        }

        private void SearchConnectorTypes()
        {
            connectorTypes.Add(
                new ConnectorType() { Name = "Metablog", Assembly = "MyPublisher.Connectors.Blog.dll", Type = "MyPublisher.Connectors.MetaBlogConnector" });
        }

        private void SearchLocationTypes()
        {
            locationTypes.Add(
                new LocationType() { Name = "Windows", Assembly = "MyPublisher.Framework.dll", Type = "MyPublisher.Framework.Location" });
            locationTypes.Add(
                new LocationType() { Name = "Blog", Assembly = "MyPublisher.Framework.dll", Type = "MyPublisher.Framework.Location" });
        }

        private void SearchProcessTypes()
        {
            processTypes.Add(ProcessType.Unkonw);
            processTypes.Add(ProcessType.Unkonw);
            processTypes.Add(ProcessType.Unkonw);
            processTypes.Add(ProcessType.Unkonw);
        }

        private void SearchApplicationTypes()
        {
            RegistryKey root = Registry.ClassesRoot;
            string[] names = root.GetSubKeyNames();
            foreach (string type in names)
            {
                if (Regex.IsMatch(type, @"^\.[a-zA-z]+"))
                {
                    RegistryKey subkey = root.OpenSubKey(type);
                    string defaultApp = subkey.GetValue("") as string;
                    if (!String.IsNullOrEmpty(defaultApp))
                    {
                        RegistryKey defaultAppKey = root.OpenSubKey(defaultApp);
                        if (defaultAppKey != null)
                        {
                            RegistryKey shellKey = defaultAppKey.OpenSubKey("shell");
                            if (shellKey != null)
                            {
                                RegistryKey shellOpenKey = shellKey.OpenSubKey("open");
                                if (shellOpenKey != null)
                                {
                                    RegistryKey shellOpenCommandKey = shellOpenKey.OpenSubKey("command");
                                    if (shellOpenCommandKey != null)
                                    {
                                        string command = shellOpenCommandKey.GetValue("") as string;
                                        if (!string.IsNullOrEmpty(command) && filters.Contains(type))
                                        {
                                            appliationTypes.Add(new ApplicationType() { Name = defaultApp, Source = command, Type = type });
                                        }
                                        shellOpenCommandKey.Close();
                                    }
                                    shellOpenKey.Close();
                                }
                                shellKey.Close();
                            }
                            defaultAppKey.Close();
                        }
                    }
                    subkey.Close();
                }
            }
            root.Close();
        }
    }
}
